package org.carabiner.infinitest;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.TimerTask;
import java.util.regex.Pattern;

import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.Timer;

import org.carabiner.infinitest.depgraph.DependencyGraph;
import org.carabiner.infinitest.depgraph.JavaClass;

public class InfinitestMain implements ActionListener
{
  private Timer timer;
  private DependencyGraph index;  
  private TestRunner runner;
  private ResultListModel testResults;
  private JList list;
  private JFrame frame;

  public InfinitestMain(File[] path) throws IOException
  {
    frame = new JFrame();
    frame.setPreferredSize(new Dimension(480, 0));
    frame.setAlwaysOnTop(true);
    frame.setLayout(new BorderLayout());
    testResults = new ResultListModel();
    list = new JList(testResults);
    frame.add(list, BorderLayout.CENTER);
    Pattern testPattern = Pattern.compile(InfinitestSettings.getTestPattern());
    index = new DependencyGraph(path, testPattern);
    runner = new JUnitRunner();
    runner.addTestStatusListener(testResults);
    timer = new Timer(InfinitestSettings.getRefreshRate(), this);
    timer.start();
    frame.pack();
  }
  
  private Set<String> getNames(Set<JavaClass> testsToRun)
  {
    Set<String> names = new HashSet<String>();
    for(JavaClass clazz : testsToRun)
    {
      names.add(clazz.getName());
    }
    return names;
  }

  public void actionPerformed(ActionEvent e)
  {
    try
    {      
      int resultSize = testResults.size();
      Set<JavaClass> testsToRun = index.update();
      if (testsToRun.size() != 0)
        list.setBackground(Color.YELLOW);
      for(String testName : getNames(testsToRun))
      {
        frame.setTitle("Running test: " + testName);        
        runner.runTest(testName);            
      }
      if (testResults.size() == 0)
      {
        list.setBackground(Color.GREEN);
        frame.setTitle("");
      }
      else
      {
        list.setBackground(Color.RED);
        frame.setTitle("Failures Detected");
      }
      if (resultSize != testResults.size())
        frame.pack();
    }
    catch (IOException ex)
    {
      throw new RuntimeException(ex);
    }    
  }

  public static void main(String[] args) throws IOException
  {
    File[] buildPath = new File[args.length];
    for(int i = 0; i < args.length; i++)
    {
      buildPath[i] = new File(args[i]);
      if (!buildPath[i].exists())
        System.err.println("Warning: " + buildPath[i] + " does not exist");
    }
    InfinitestMain app = new InfinitestMain(buildPath);
    app.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    app.frame.pack();
    app.frame.setVisible(true);
  }

  JList getList()
  {
    return list;
  }

  JFrame getFrame()
  {
    return frame;
  }
}
